import { SDKSystem } from "../system/SDKSystem";
import { BaseShare } from "../share/BaseShare";
import BaseFileSystem from "../fileSystem/BaseFileSystem";
import BaseSubPackage from "../subPackage/BaseSubPackage";
import SDKEvent from "../../tools/SDKEvent";
import BaseLogin from "../login/BaseLogin";
import BaseRecorder from "../recorder/BaseRecorder";
import BaseScreenshot from "../screenshot/BaseScreenshot";
import { SDKAdParam, SDKDataType } from "../../SDKDefine";
import { SDKChannelType, SDKDataItemInfo } from "../../SDKConfig";
import { createClass } from "../../../cfw/tools/class_decorator";
import { BaseAdMgr } from "../base/BaseAdMgr";


export abstract class BaseChannel {
    id: string = ''
    protected data: SDKDataType = null;;
    protected config: SDKChannelType = null;;

    system: SDKSystem = null;

    share: BaseShare = null;

    fileSystem: BaseFileSystem = null;

    subPackage: BaseSubPackage = null;

    event: SDKEvent = null;

    login: BaseLogin = null;

    recorder: BaseRecorder = null;

    screenshot: BaseScreenshot = null;



    protected adMgrMap: { [key: string]: BaseAdMgr } = {}

    openAd(name: string, param: SDKAdParam) {
        let ins = this.adMgrMap[name]
        if (ins) {
            ins.open(param)
        }
    }

    closeAd(name: string, index: number = 0) {
        let ins = this.adMgrMap[name]
        if (ins) {
            ins.close(index)
        }
    }

    getAd(name: string): BaseAdMgr {
        return this.adMgrMap[name]
    }

    hasAd(name: string): boolean {
        return this.adMgrMap[name] != undefined;
    }

    initAds() {
        const ads: { [key: string]: SDKDataItemInfo } = this.config.ads;
        if (ads) {
            for (const key in ads) {
                if (Object.prototype.hasOwnProperty.call(ads, key)) {
                    let item: SDKDataItemInfo = ads[key]

                    let mgr: BaseAdMgr = createClass(item.mgrName)
                    if (mgr) {
                        mgr.setSystem(this.system)
                        this.adMgrMap[key] = mgr;
                        mgr.setCfg(item)
                        if (this.data[key]) {
                            mgr.setData(this.data[key])
                        }
                        if (!item.version || this.system.compareVersion(item.version) >= 0) {
                            mgr.init()
                        }

                    }

                }
            }
        }

    }

    protected initPlatform() {

    }


    init(id: string, data: SDKDataType, config: SDKChannelType, sdk: any = null) {
        this.id = id;
        this.data = data;
        this.config = config;
        this.initPlatform()
        if (config.system) {
            this.system = createClass(config.system)
            if (this.system) {
                this.system.setSDK(sdk)
                this.system.setData(config)
                this.system.init()
            }
        }


        this.initAds();




        if (config.event) {
            this.event = createClass(config.event)
        }

        if (config.share) {
            this.share = createClass(config.share)
            this.share.setSystem(this.system)
            this.share.setData(data.share)
            this.share.init()
        }

        if (config.subPackage) {
            this.subPackage = createClass(config.subPackage)
            if (this.subPackage) {
                this.subPackage.setSystem(this.system)
            }
        }

        if (config.recorder) {
            this.subPackage = createClass(config.recorder)
            if (this.recorder) {
                this.recorder.setSystem(this.system)
                this.recorder.init()
            }
        }

        if (config.screenshot) {
            this.screenshot = createClass(config.screenshot)
            if (this.screenshot) {
                this.screenshot.setSystem(this.system)
            }
        }
        if (config.fileSystem) {
            this.fileSystem = createClass(config.fileSystem)
            if (this.fileSystem) {
                this.fileSystem.setSystem(this.system)
                this.fileSystem.init()
            }
        }


        if (config.login) {
            this.login = createClass(config.login)
            if (this.login) {
                this.login.setSystem(this.system)
            }
        }
    }

    hasConfig(name: string) {
        return this.config[name]
    }

}